package jinyilw.swing.visuals;

import jinyilw.swing.ColorTools;
import jinyilw.swing.NativeTools;
import jinyilw.swing.ScreenTools;
import jinyilw.common.Operator;
import jinyilw.swing.DragCompUtils;
import jinyilw.swing.i18n.ICSetting;
import jinyilw.swing.rlaf.UITools;
import jinyilw.swing.rlaf.theme.RRootPaneSet;
import jinyilw.swing.rlaf.ui.RLayoutAdapter;
import jinyilw.swing.rlaf.utils.RLafUtils;
import jinyilw.swing.visuals.panel.FlatImagePanel;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JRootPane;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.geom.RoundRectangle2D;

public class FlatFrame extends JFrame // 扁平窗体
{
	private static final long serialVersionUID = -3572539935903245872L;
	private final FlatImagePanel backgroundPanel = new FlatImagePanel();
	private Container contentPanel = new Container();
	private TitlePane titlePane;
	private Container menu;
	private int titleHeight, menuHeight = 0;
	private int section = 0;
	private Dimension maxDimension;
	private Dimension defaultDimension;
	protected boolean rounded = true;
	private boolean transparent = false;
	Dimension preferredSize;

	static
	{
		UITools.initRLookAndFeel();
	}

	public FlatFrame()
	{
		initGUI();
	}

	public FlatFrame(String title)
	{
		super(title);
		initGUI();
	}

	public FlatFrame(String title, GraphicsConfiguration gc)
	{
		super(title, gc);
		initGUI();
	}

	private void initGUI()
	{
		maxDimension = ScreenTools.getDefaultScreenSize();
		int w = (int) (maxDimension.width * 0.6);
		int h = (int) (maxDimension.height * 0.6);
		defaultDimension = new Dimension(w, h);
		titlePane = new TitlePane(backgroundPanel, this);
		titleHeight = titlePane.getTitleHeight();
		super.setContentPane(backgroundPanel);
		backgroundPanel.setLayout(new FlatLayout());
		backgroundPanel.add(titlePane);
		backgroundPanel.add(contentPanel);
		contentPanel.setLayout(new BorderLayout());
		DragCompUtils.setMovable(backgroundPanel, this);
		setTransparent(true);
	}

	public void setTransparent(boolean b)
	{
		if (!RLafUtils.transparentEnable)
			return;
		if (transparent == b)
			return;
		transparent = b;
		if (b)
		{
			setBackground(ColorTools.transparentColor);
			// root.getLayeredPane().setOpaque(true);
		} else
		{
			setBackground(RRootPaneSet.getRootPaneSet().bgColor);
			getLayeredPane().setOpaque(false);
			Container c = getContentPane();
			if (c instanceof JComponent)
				((JComponent) c).setOpaque(false);
		}
	}

	public void setCustomBGImage(Image img)
	{
		backgroundPanel.setCustomImage(img);
	}
	public void setCustomAlpha(float alpha)
	{
		backgroundPanel.setCustomAlpha(alpha);
	}

	public void setContentPanel(Container container)
	{
		if (container == null || container == contentPanel)
			return;
		container.setBounds(contentPanel.getBounds());
		backgroundPanel.remove(contentPanel);
		backgroundPanel.add(container);
		backgroundPanel.validate();
		container.repaint();
		contentPanel = container;
	}

	@Override
	public void setContentPane(Container container)
	{
		setContentPanel(container);
	}

	@Override
	public Container getContentPane()
	{
		return contentPanel;
	}

	public FlatImagePanel getBackgroundPanel()
	{
		return backgroundPanel;
	}

	@Override
	protected JRootPane createRootPane()
	{
		JRootPane rp = new NoneRootPane();
		rp.setOpaque(true);
		return rp;
	}

	@Override
	public void setBounds(int x, int y, int width, int height)
	{
		boolean resized = width != getWidth() || height != getHeight();
		super.setBounds(x, y, width, height);
		if (resized && rounded)
			setShape(new RoundRectangle2D.Double(0, 0, width, height, 6, 6));
	}

	public void setTitle(ICSetting iSetting)
	{
		titlePane.setTitle(iSetting);
	}

	public void setSection(int n)
	{
		if (n == section)
			return;
		section = n;
		if (contentPanel != null)
			contentPanel.setBounds(section, titleHeight + menuHeight,
					getWidth() - 2 * section,
					getHeight() - titleHeight - menuHeight - section);
	}

	public int getSection()
	{
		return section;
	}

	@Override
	public void setResizable(boolean b)
	{
		super.setResizable(b);
		if (b)
		{
			if (section == 0)
				setSection(1);
			DragCompUtils.setResizeable2(backgroundPanel, this);
		}
	}

	public boolean isRounded()
	{
		return rounded;
	}

	public void setRounded(boolean b)
	{
		rounded = b;
		if (b)
			setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(),
					6, 6));
		else
			setShape(null);
	}

	@Override
	public void setIconImage(Image image)
	{
		super.setIconImage(image);
		NativeTools.setMacDockImage(image);
	}

	public void cancelClosing()
	{
		titlePane.cancelClosing();
	}

	public void addBeforeClosingOperator(Operator<?> operator)
	{
		titlePane.addBeforeClosingOperator(operator);
	}

	public void addClosingOperator(Operator<?> operator)
	{
		titlePane.addClosingOperator(operator);
	}

	public void addHideOperator(final Operator<?> operator)
	{
		titlePane.addHideOperator(operator);
	}

	public void addMoveReleaseOperator(final Operator<?> operator)
	{
		DragCompUtils.addMoveReleaseOperator(backgroundPanel, operator);
	}

	public void setCustomMenubar(Container m)
	{
		if (menu == m)
			return;
		if (menu != null)
		{
			backgroundPanel.remove(menu);
			menuHeight = 0;
		}
		menu = m;
		if (menu != null)
		{
			menuHeight = Math.max(18, menu.getHeight());
			backgroundPanel.add(menu);
		}
		backgroundPanel.doLayout();
	}

	@Override
	public void setJMenuBar(JMenuBar menubar)
	{
		setCustomMenubar(menubar);
	}

	public void setTitleHeight(int h)
	{
		if (h == titleHeight)
			return;
		titleHeight = h;
		titlePane.setTitleHeight(h);
		backgroundPanel.doLayout();
	}

	public void setTitleColor(Color color)
	{
		titlePane.setTitleColor(color);
	}

	public void setTitleFont(Font font)
	{
		titlePane.setTitleFont(font);
	}

	public void setMenuHeight(int height)
	{
		menuHeight = height;
	}

	public void setMaxDimension(Dimension d)
	{
		maxDimension = d;
	}

	public void setDefaultDimension(Dimension d)
	{
		defaultDimension = d;
	}

	public void setDefaultDimensionRatio(double wr, double hr)
	{
		int w = (int) (maxDimension.width * wr);
		int h = (int) (maxDimension.height * hr);
		defaultDimension = new Dimension(w, h);
	}

	public void defaultSize()
	{
		setSize(defaultDimension);
	}

	public void maxSize()
	{
		setSize(maxDimension);
	}

	@Override
	public Dimension getPreferredSize()
	{
		if (!(isPreferredSizeSet() || isValid()))
		{
			synchronized (getTreeLock())
			{
				preferredSize = contentPanel.getPreferredSize();
				preferredSize.height += (titleHeight + menuHeight + section);
				preferredSize.width += section * 2;
			}
		}
		return preferredSize;
	}

	private class FlatLayout extends RLayoutAdapter
	{
		@Override
		public void layoutContainer(Container parent)
		{
			int width = parent.getWidth();
			titlePane.setBounds(0, 0, width, titleHeight);
			if (menu != null && menuHeight > 0)
				menu.setBounds(0, titleHeight, width, menuHeight);
			if (contentPanel != null)
				contentPanel.setBounds(section, titleHeight + menuHeight,
						width - 2 * section, parent.getHeight() - titleHeight
								- menuHeight - section);
		}
	}
}
